﻿// ------------------------------------------------------------------------
// 项目名称：Canroc.Net 
// 版权归属：Canroc（https://gitee.com/canroc）
//
// 许可证信息
// Canroc.Net项目主要遵循 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-APACHE 文件。
//
// 使用条款：
// 1.使用本项目应遵守相关法律法规和许可证的要求。
// 2.不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动。
// 3.任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任
//
// 免责声明
// 对于因使用本代码而产生的任何直接、间接、偶然、特殊或后果性损害，我们不承担任何责任。
//
// 其他重要信息
// Canroc.Net 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。
// ------------------------------------------------------------------------

namespace Canroc.Net.RemoteHttp.WeChatPay.Dto;

/// <summary>
///     微信支付下单请求输入项
/// </summary>
public class WeChatPayApiPlaceInput
{
    /// <summary>
    ///     公众号ID
    /// </summary>
    [Required]
    [MaxLength(32)]
    [JsonPropertyName("appid")]
    public string AppId { get; set; } = string.Empty;

    /// <summary>
    ///     直连商户号
    /// </summary>
    [Required]
    [MaxLength(32)]
    [JsonPropertyName("mchid")]
    public string MchId { get; set; } = string.Empty;

    /// <summary>
    ///     商品描述
    /// </summary>
    [Required]
    [MaxLength(127)]
    [JsonPropertyName("description")]
    public string Description { get; set; } = string.Empty;

    /// <summary>
    ///     商户订单号
    /// </summary>
    /// <remarks>
    ///     商户系统内部订单号，只能是数字、大小写字母_-*且在同一个商户号下唯一。
    /// </remarks>
    [Required]
    [MaxLength(32)]
    [JsonPropertyName("out_trade_no")]
    public string OutTradeNo { get; set; } = string.Empty;

    /// <summary>
    ///     交易结束时间
    /// </summary>
    /// <remarks>
    ///     订单失效时间，遵循rfc3339标准格式，
    ///     格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE，
    ///     yyyy-MM-DD表示年月日，
    ///     T出现在字符串中，表示time元素的开头，
    ///     HH:mm:ss表示时分秒，
    ///     TIMEZONE表示时区（+08:00表示东八区时间，领先UTC8小时，即北京时间）。
    ///     例如：2015-05-20T13:29:35+08:00表示，北京时间2015年5月20日13点29分35秒。
    /// </remarks>
    [MaxLength(64)]
    [JsonPropertyName("time_expire")]
    public string? TimeExpire { get; set; }

    /// <summary>
    ///     附加数据
    /// </summary>
    /// <remarks>
    ///     附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用，实际情况下只有支付完成状态才会返回该字段。
    /// </remarks>
    [MaxLength(128)]
    [JsonPropertyName("attach")]
    public string? Attach { get; set; }

    /// <summary>
    ///     通知地址
    /// </summary>
    /// <remarks>
    ///     异步接收微信支付结果通知的回调地址，通知URL必须为外网可访问的URL，不能携带参数。 公网域名必须为HTTPS，如果是走专线接入，使用专线NAT IP或者私有回调域名可使用HTTP
    /// </remarks>
    [Required]
    [MaxLength(255)]
    [JsonPropertyName("notify_url")]
    public string? NotifyUrl { get; set; }

    /// <summary>
    ///     订单优惠标记
    /// </summary>
    [MaxLength(32)]
    [JsonPropertyName("goods_tag")]
    public string? GoodsTag { get; set; }

    /// <summary>
    ///     电子发票入口开放标识
    /// </summary>
    /// <remarks>
    ///     传入true时，支付成功消息和支付详情页将出现开票入口。需要在微信支付商户平台或微信公众平台开通电子发票功能，传此字段才可生效。
    /// </remarks>
    [JsonPropertyName("support_fapiao")]
    public bool? SupportFapiao { get; set; }

    /// <summary>
    ///     订单金额
    /// </summary>
    [Required]
    [JsonPropertyName("amount")]
    public CommReqAmountInfo Amount { get; set; } = new();

    /// <summary>
    ///     支付者
    /// </summary>
    [Required]
    [JsonPropertyName("payer")]
    public JsapiReqPayerInfo Payer { get; set; } = new();

    /// <summary>
    ///     优惠功能
    /// </summary>
    [JsonPropertyName("detail")]
    public OrderDetail? Detail { get; set; }

    /// <summary>
    ///     场景信息
    /// </summary>
    [JsonPropertyName("scene_info")]
    public CommReqSceneInfo? SceneInfo { get; set; }

    /// <summary>
    ///     结算信息
    /// </summary>
    [JsonPropertyName("settle_info")]
    public SettleInfo? SettleInfo { get; set; }
}

/// <summary>
///     微信支付-订单金额
/// </summary>
public class CommReqAmountInfo
{
    /// <summary>
    ///     总金额
    /// </summary>
    /// <remarks>
    ///     订单总金额，单位为分。
    /// </remarks>
    [Required]
    [JsonPropertyName("total")]
    public int Total { get; set; }

    /// <summary>
    ///     货币类型
    /// </summary>
    /// <remarks>
    ///     CNY：人民币，境内商户号仅支持人民币。
    /// </remarks>
    [Required]
    [MaxLength(16)]
    [JsonPropertyName("currency")]
    public string Currency { get; set; } = "CNY";
}

/// <summary>
///     微信支付-支付者信息
/// </summary>
public class JsapiReqPayerInfo
{
    /// <summary>
    ///     用户标识
    /// </summary>
    /// <remarks>
    ///     用户在普通商户AppID下的唯一标识。 下单前需获取到用户的OpenID。
    /// </remarks>
    [Required]
    [MaxLength(128)]
    [JsonPropertyName("openid")]
    public string OpenId { get; set; } = string.Empty;
}

/// <summary>
///     微信支付-优惠功能
/// </summary>
public class OrderDetail
{
    /// <summary>
    ///     订单原价
    /// </summary>
    /// <remarks>
    ///     1、商户侧一张小票订单可能被分多次支付，订单原价用于记录整张小票的交易金额。
    ///     2、当订单原价与支付金额不相等，则不享受优惠。
    ///     3、该字段主要用于防止同一张小票分多次支付，以享受多次优惠的情况，正常支付订单不必上传此参数。
    /// </remarks>
    [JsonPropertyName("cost_price")]
    public int? CostPrice { get; set; }

    /// <summary>
    ///     商品小票ID
    /// </summary>
    [MaxLength(32)]
    [JsonPropertyName("invoice_id")]
    public string? InvoiceId { get; set; }

    /// <summary>
    ///     单品列表
    /// </summary>
    [Required]
    [JsonPropertyName("goods_detail")]
    public List<GoodsDetail> GoodsDetail { get; set; } = [];
}

/// <summary>
///     微信支付-商品详情
/// </summary>
public class GoodsDetail
{
    /// <summary>
    ///     商品编码
    /// </summary>
    /// <remarks>
    ///     由半角的大小写字母、数字、中划线、下划线中的一种或几种组成。
    /// </remarks>
    [Required]
    [MaxLength(32)]
    [JsonPropertyName("merchant_goods_id")]
    public string MerchantGoodsId { get; set; } = string.Empty;

    /// <summary>
    ///     微信支付商品编码
    /// </summary>
    /// <remarks>
    ///     微信支付定义的统一商品编号（没有可不传）
    /// </remarks>
    [MaxLength(32)]
    [JsonPropertyName("wechatpay_goods_id")]
    public string? WechatpayGoodsId { get; set; }

    /// <summary>
    ///     商品名称
    /// </summary>
    /// <remarks>
    ///     商品的实际名称
    /// </remarks>
    [MaxLength(256)]
    [JsonPropertyName("goods_name")]
    public string? GoodsName { get; set; }

    /// <summary>
    ///     商品数量
    /// </summary>
    [Required]
    [JsonPropertyName("quantity")]
    public int Quantity { get; set; }

    /// <summary>
    ///     商品单价
    /// </summary>
    /// <remarks>
    ///     单位为：分。如果商户有优惠，需传输商户优惠后的单价(例如：用户对一笔100元的订单使用了商场发的纸质优惠券100-50，则活动商品的单价应为原单价-50)
    /// </remarks>
    [Required]
    [JsonPropertyName("unit_price")]
    public int UnitPrice { get; set; }
}

/// <summary>
///     微信支付-场景信息
/// </summary>
public class CommReqSceneInfo
{
    /// <summary>
    ///     用户终端IP
    /// </summary>
    /// <remarks>
    ///     用户的客户端IP，支持IPv4和IPv6两种格式的IP地址。
    /// </remarks>
    [MaxLength(45)]
    [JsonPropertyName("payer_client_ip")]
    public string? PayerClientIp { get; set; }

    /// <summary>
    ///     商户端设备号
    /// </summary>
    /// <remarks>
    ///     商户端设备号（门店号或收银设备ID）。
    /// </remarks>
    [MaxLength(32)]
    [JsonPropertyName("device_id")]
    public string DeviceId { get; set; } = string.Empty;

    /// <summary>
    ///     商户门店信息
    /// </summary>
    [JsonPropertyName("store_info")]
    public StoreInfo? StoreInfo { get; set; }
}

/// <summary>
///     微信支付-商户门店信息
/// </summary>
public class StoreInfo
{
    /// <summary>
    ///     门店编号
    /// </summary>
    /// <remarks>
    ///     商户侧的门店编号，由商户自定义。
    /// </remarks>
    [Required]
    [MaxLength(32)]
    [JsonPropertyName("id")]
    public string Id { get; set; } = string.Empty;

    /// <summary>
    ///     商户侧的门店名称
    /// </summary>
    /// <remarks>
    ///     商户侧的门店名称，由商户自定义。
    /// </remarks>
    [MaxLength(256)]
    [JsonPropertyName("name")]
    public string Name { get; set; } = string.Empty;

    /// <summary>
    ///     地区编码
    /// </summary>
    /// <remarks>
    ///     地区编码，详细请见省市区编号对照表。
    /// </remarks>
    [MaxLength(32)]
    [JsonPropertyName("area_code")]
    public string AreaCode { get; set; } = string.Empty;

    /// <summary>
    ///     详细地址
    /// </summary>
    /// <remarks>
    ///     详细的商户门店地址。
    /// </remarks>
    [MaxLength(512)]
    [JsonPropertyName("address")]
    public string Address { get; set; } = string.Empty;
}

/// <summary>
///     微信支付-结算信息
/// </summary>
public class SettleInfo
{
    /// <summary>
    ///     是否指定分账
    /// </summary>
    /// <remarks>
    ///     是否指定分账，枚举值：true：是 false：否
    /// </remarks>
    [JsonPropertyName("profit_sharing")]
    public bool ProfitSharing { get; set; }
}